﻿using System.Text;
using System.Text.RegularExpressions;

namespace Armon.Lib.Extensions.Text
{
    public static class StringExtension
    {
        public static byte[] ToBytes(this string s, Encoding? encoding = null)
        {
            encoding ??= Encoding.UTF8;
            return encoding.GetBytes(s);
        }

        public static int Count(this string s, string t)
        {
            ArgumentNullException.ThrowIfNull(s);
            ArgumentNullException.ThrowIfNull(t);
            return Regex.Matches(s, t).Count;
        }

        public static List<string> Split(this string s, params char[]? separator)
        {
            ArgumentNullException.ThrowIfNull(s);
            return [.. s.Split(separator)];
        }

        public static int GetLengthByEncoding(this string s, Encoding? encoding = null)
        {
            ArgumentNullException.ThrowIfNull(s);

            encoding ??= Encoding.UTF8;
            return encoding.GetByteCount(s);
        }

        public static string ToSBC(this string s)
        {
            ArgumentNullException.ThrowIfNull(s);

            var c = s.ToCharArray();
            for (var i = 0; i < c.Length; i++)
            {
                if (c[i] == 32)
                {
                    c[i] = (char)12288;
                    continue;
                }
                if (c[i] < 127) 
                {
                    c[i] = (char)(c[i] + 65248);
                }
            }
            return new string(c);
        }

        public static string ToDBC(this string s)
        {
            ArgumentNullException.ThrowIfNull(s);

            var c = s.ToCharArray();
            for (var i = 0; i < c.Length; i++)
            {
                if (c[i] == 12288)
                {
                    c[i] = (char)32;
                    continue;
                }
                if (c[i] > 65280 && c[i] < 65375)
                    c[i] = (char)(c[i] - 65248);
            }
            return new string(c);
        }

        public static int ToInt(this string s) 
        {
            if (!int.TryParse(s, out int result)) 
            {
                return 0;
            }
            return result;
        }

        public static double ToDouble(this string s)
        {
            if (!double.TryParse(s, out double result))
            {
                return 0;
            }
            return result;
        }

        public static bool IsCapitalized(this string s)
        {
            if (string.IsNullOrEmpty(s)) 
            {
                return false;
            }

            return char.IsUpper(s[0]);
        }
    }
}
